/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package util.collectionStats;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.EnumMap;

import util.exceptions.StatsRegistryException;

/**
 * 
 * @author i_khri
 */
public class CollectionStatsRegistry {

	public enum Stats {
		TOTAL_DOCS, AVG_DOC_LENGTH, DOCS_LENGHTS
	}

	/**
	 * 
	 * @param path
	 *            where all files and information are stored
	 * @return collection statistic registry
	 * @throws FileNotFoundException
	 * @throws StatsRegistryException
	 */
	public static CollectionStatsRegistry statsRegistryFromFile(String path)
			throws FileNotFoundException, StatsRegistryException {
		CollectionStatsRegistry csr = new CollectionStatsRegistry();
		FileInputStream fis = new FileInputStream(path);
		try {
			ObjectInputStream ois = new ObjectInputStream(fis);
			csr.statsMap = (EnumMap<Stats, Object>) ois.readObject();
			ois.close();
		} catch (IOException e) {
			StatsRegistryException sre = new StatsRegistryException(
					"Registry file is broken. File [" + path + "].");
			try {
				sre.initCause(e);
			} catch (Exception ignore) {
			} finally {
				throw sre;
			}
		} catch (ClassNotFoundException e) {
			StatsRegistryException sre = new StatsRegistryException(
					"No registry found in the registry file [" + path + "].");
			try {
				sre.initCause(e);
			} catch (Exception ignore) {
			} finally {
				throw sre;
			}
		}

		return csr;
	}

	/**
	 * 
	 * @param statName
	 * @param value
	 */
	public void setStat(Stats statName, Object value) {
		statsMap.put(statName, value);
	}

	/**
	 * 
	 * @param statName
	 *            : object which holds the name of the statistic being requested
	 * @return value of statistic is returned as string
	 */
	public String getString(Stats statName) {
		return String.valueOf(statsMap.get(statName));
	}

	/**
	 * 
	 * @param statName
	 *            : object which holds the name of the statistic being requested
	 * @return value of statistic is returned as an integer
	 * @throws StatsRegistryException
	 */
	public int getInt(Stats statName) throws StatsRegistryException {
		try {
			return Integer.class.cast(statsMap.get(statName));
		} catch (ClassCastException e) {
			throw new StatsRegistryException("No integer value for statistic "
					+ statName + " was found.");
		}
	}

	/**
	 * 
	 * 
	 * @param statName
	 *            : object which holds the name of the statistic being requested
	 * @return value of statistic is returned as a double
	 * @throws StatsRegistryException
	 */
	public double getDouble(Stats statName) throws StatsRegistryException {
		try {
			return Double.class.cast(statsMap.get(statName));
		} catch (ClassCastException e) {
			throw new StatsRegistryException("No double value for statistic "
					+ statName + " was found.");
		}
	}

	/**
	 * 
	 * @param statName
	 *            : object which holds the name of the statistic being requested
	 * @return Object of statistic matching the name provided is returned
	 * @return
	 */
	public Object getObject(Stats statName) {
		return statsMap.get(statName);
	}

	/**
	 * 
	 * @param path
	 *            in which information will be stored.
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	public void saveTo(String path) throws FileNotFoundException, IOException {
		FileOutputStream fos = new FileOutputStream(path);
		ObjectOutputStream oos = new ObjectOutputStream(fos);
		oos.writeObject(statsMap);
		oos.close();
	}

	/**
	 * The clear() empties the enumMap
	 */
	public void clear() {
		statsMap.clear();
	}

	/**
	 * Constructor
	 */
	public CollectionStatsRegistry() {
		statsMap = new EnumMap<Stats, Object>(Stats.class);
	}

	private EnumMap<Stats, Object> statsMap = new EnumMap<Stats, Object>(
			Stats.class);
}
